import { SoundDefine, SoundManager } from '../../base/manger/SoundManager';

const { ccclass, property, menu } = cc._decorator;
@ccclass
@menu('ISV/按钮组件/BaseButton')

export class BaseButton extends cc.Component {

    /**启用声音 */
    @property({
        tooltip: "启用声音",
    })
    enableSound = true;

    // @property({
    //     type: SoundDefine,
    //     visible: function () { return (this as any).enableSound }
    // })
    // sound: SoundDefine = SoundDefine.TouchButton

    /**点击目标 */
    @property(cc.Node)
    target: cc.Node = null

    @property(cc.Float)
    scaleTo = 0.8;

    @property(cc.Float)
    duration = 0.3

    @property(cc.SpriteFrame)
    normaleSpriteFrame: cc.SpriteFrame = null

    @property(cc.SpriteFrame)
    disabledSpriteFrame: cc.SpriteFrame = null

    /**点击间隔 */
    @property(cc.Integer)
    clickInterval = 0

    private _interactable = true;
    @property
    public get interactable() {
        return this._interactable;
    }
    public set interactable(value) {
        this._interactable = value;
        this.updateMaterial()
    }

    private _isGray = false;
    @property
    public get isGray() {
        return this._isGray;
    }
    public set isGray(value) {
        this._isGray = value;
        this.updateMaterial()
    }

    scaleFrom = 1

    @property(cc.Component.EventHandler) clickEvents: cc.Component.EventHandler[] = []
    @property(cc.Component.EventHandler) touchStartEvents: cc.Component.EventHandler[] = []
    @property(cc.Component.EventHandler) touchCancelEvents: cc.Component.EventHandler[] = []

    onLoad() {
        if (!this.target) {
            this.target = this.node
        }
        this.node.on(cc.Node.EventType.TOUCH_START, this.onTouchStart, this)
        this.node.on(cc.Node.EventType.TOUCH_END, this.onTouchEnd, this)
        this.node.on(cc.Node.EventType.TOUCH_CANCEL, this.onTouchCancel, this)
        this.updateMaterial()
    }


    onDestory() {
        this.node.off(cc.Node.EventType.TOUCH_START, this.onTouchStart, this)
        this.node.off(cc.Node.EventType.TOUCH_END, this.onTouchEnd, this)
        this.node.off(cc.Node.EventType.TOUCH_CANCEL, this.onTouchCancel, this)
    }

    scaleTween: cc.Tween<any> = null

    onTouchStart(event) {
        // console.log("BaseButton onTouchStart")
        if (!this.interactable) return
        this.clearTween()
        this.scaleTween = cc.tween(this.target).to(this.duration, { scale: this.scaleTo }, { easing: 'expoOut' }).start()
        if (this.enableSound) {
            //console.log("播放点击音效")
        }
        cc.Component.EventHandler.emitEvents(this.touchStartEvents, this.target)

    }

    /**上次点击反应时间 */
    lastClickReactTime = 0

    onTouchEnd(event) {
        // console.log("BaseButton onTouchEnd")
        if (!this.interactable) return
        this.clearTween()
        this.scaleTween = cc.tween(this.target).to(this.duration, { scale: this.scaleFrom }, { easing: 'expoOut' }).start()
        if (this.clickInterval && Date.now() - this.lastClickReactTime < this.clickInterval * 1000) {
            console.log("BaseButton点击间隔太短")
            return
        }
        cc.Component.EventHandler.emitEvents(this.clickEvents, this.target)
        this.lastClickReactTime = Date.now()
    }

    clearTween() {
        if (this.scaleTween) {
            this.scaleTween.stop()
            this.scaleTween = null
        }
    }
    onTouchCancel(event) {
        // console.log("BaseButton onTouchCancel")
        if (!this.interactable) return
        this.clearTween()
        this.scaleTween = cc.tween(this.target).to(this.duration, { scale: this.scaleFrom }, { easing: 'expoOut' }).start()
        cc.Component.EventHandler.emitEvents(this.touchCancelEvents, this.target)

    }


    updateMaterial() {
        const sprite = this.getComponent(cc.Sprite)
        const isGray = this.isGray || !this.interactable
        if (sprite) {
            if (this.normaleSpriteFrame && this.disabledSpriteFrame) {
                sprite.spriteFrame = !isGray ? this.normaleSpriteFrame : this.disabledSpriteFrame
            } else {
                const material = cc.MaterialVariant.getBuiltinMaterial(!isGray ? '2d-sprite' : '2d-gray-sprite')
                sprite.setMaterial(0, material)
            }
        }
    }
}

